/*
 *  AS IS License 
 * ==Naive Coders==
 */
package com.naivecoders.refex;

import java.util.ArrayList;
import java.util.List;

import com.naivecoders.refex.functions.AbstractFunction;

/**
 *
 * @author andrew
 */
public class FunctionBuilder {

    private final FunctionFactory factory;
    private FName declaredName; // set only for function declaration
    private final List<AbstractFunction> arguments = new ArrayList<>();

    public FunctionBuilder(FunctionFactory factory) {
        super();
        this.factory = factory;
    }

    public void add(AbstractFunction a) {
        arguments.add(a);
    }

    public void add(FName lbl) throws InternalTypeCheckException {
        if (lbl.isElementary()) {
           add(factory.elementary(lbl.asElementary()));
        } else if (lbl.isArgument()) {
            add(factory.argument(lbl));
        } else {
//            add(factory.invoke());
//            add(factory.substitudeArguments());
            add(factory.resolve(lbl));
        }
    }

    public void setDeclaredName(FName declaredName) {
        this.declaredName = declaredName;
    }

    public FName getDeclaredName() {
        return declaredName;
    }

    public AbstractFunction build() throws InternalTypeCheckException {
        if (declaredName != null) {
            if (arguments.size() != 1) {
                throw new InternalTypeCheckException("Syntax error in declaration");
            }
            return arguments.get(0);
        }
        return factory.list(arguments);
    }

    protected FunctionFactory getFactory() {
        return factory;
    }

    protected List<AbstractFunction> getArguments() {
        return arguments;
    }
 
    @Override
    public String toString() {
        return arguments.toString();
    }
}
